package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Calendar;
import java.util.concurrent.CopyOnWriteArrayList;

public class ClientThread implements Runnable {

	private Socket clientSocket;
	private User user;

	public ClientThread(Socket clientSocket) {
		this.clientSocket = clientSocket;
		user = null;
	}

	@Override
	public void run() {
		try {
			PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
					true);
			BufferedReader in = new BufferedReader(new InputStreamReader(
					clientSocket.getInputStream()));
			String inputLine, outputLine;

			while ((inputLine = in.readLine()) != null) {
				System.out.println(inputLine + " # received from " + ((user == null) ? "unknown" : user.getName()));
				outputLine = "no output";
				if (inputLine.equals("!list")) {
					outputLine = "No running auctions";
					CopyOnWriteArrayList<Auction> running = ServerManager
							.getInstance().getOnlyRunningAuctions();
					if (!running.isEmpty()) {
						outputLine = "";
						for (Auction a : running) {
							outputLine += a.toString() + "|";
						}
					}
				} else if (inputLine.startsWith("!login")) {
					if (user != null) {
						outputLine = "Already logged in as " + user.getName();
					} else {
						String[] splt = inputLine.split(" ");
						if (splt.length != 3) {
							outputLine = "Invalid login command";
						} else {
							String name = splt[1];
							try {
								int udpPort = Integer.parseInt(splt[2]);
								boolean wasLoggedIn = false;
								for (User u : ServerManager.getInstance()
										.getUsers()) {
									if (u.getName().equals(name)) {

										if (u.isLoggedIn()) {
											wasLoggedIn = true;
											outputLine = "You are already logged in on another terminal!";
										} else {
											user = u;
											user.setLoggedIn(true);
											user.setAddress(clientSocket
													.getInetAddress());
											user.setUdpPort(udpPort);
										}
										break;
									}
								}

								if (!wasLoggedIn) {
									if (user == null) {
										user = new User(name,
												clientSocket.getInetAddress(),
												udpPort);
										ServerManager.getInstance().getUsers()
												.add(user);
									}
									outputLine = "Successfully logged in as "
											+ user.getName();
								}
							} catch (NumberFormatException e) {
								outputLine = "Invalid login command";
							}
						}
					}
				} else if (inputLine.equals("!logout")) {
					if (user == null) {
						outputLine = "You have to login first";
					} else {
						user.setLoggedIn(false);
						user.setAddress(null);
						user.setUdpPort(0);
						outputLine = "Successfully logged out as "
								+ user.getName();
						user = null;
					}
				} else if (inputLine.startsWith("!create")) {
					String[] splt = inputLine.split(" ");
					if (splt.length < 3) {
						outputLine = "Invalid create command";
					} else {
						try {
							int duration = Integer.parseInt(splt[1]);
							String desc = "";
							for (int i = 2; i < splt.length; i++) {
								desc = desc + splt[i];
								if (i < splt.length - 1) {
									desc = desc + " ";
								}
							}

							Calendar cal = Calendar.getInstance();
							cal.add(Calendar.SECOND, duration);
							Auction a = new Auction(user, desc, cal);
							ServerManager.getInstance().getRunningAuctions()
									.add(a);

							outputLine = "An auction '" + a.getDescription()
									+ "' with id " + a.getId()
									+ " has been created and will end on "
									+ a.getDeadlineAsString();
						} catch (NumberFormatException e) {
							outputLine = "Invalid arguments for create";
						}
					}
				} else if (inputLine.startsWith("!bid")) {
					String[] splt = inputLine.split(" ");
					if (splt.length != 3) {
						outputLine = "Invalid bid command";
					} else {
						try {
							int id = Integer.parseInt(splt[1]);
							double money = Double.parseDouble(splt[2]);

							Auction a = ServerManager.getInstance().getAuction(
									id);

							if (a == null) {
								outputLine = "Error, auction with id " + id
										+ " not found.";
							} else {
								int moneyInt = (int) (money * 100.0);
								if (a.getHighestBid() < moneyInt) {
									a.setHighestBid(moneyInt);
									User hBidder = a.getHighestBidder();
									a.setHighestBidder(user);
									outputLine = "You successfully bid with "
											+ money + " on '"
											+ a.getDescription() + "'";
									if (hBidder != null) {
										UdpSender.getInstance().sendMessage(
												"!new-bid "
														+ a.getDescription(),
												hBidder);
									}
								} else {
									double hBid = a.getHighestBid() / 100.0;
									outputLine = "You unsuccessfully bid with "
											+ money + " on '"
											+ a.getDescription()
											+ "'. Current highest bid is "
											+ hBid;
								}
							}
						} catch (NumberFormatException exc) {
							outputLine = "Invalid command arguments.";
						}
					}
				} else {
					outputLine = "Unrecognized command '" + inputLine + "'";
				}

				out.println(outputLine);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
